package main

import (
	"fmt"
)

// 递归函数
// 定义：一个函数自己调用自己，就叫做递归函数
// 递归函数需要有一个出口，逐渐向出口靠近，没有出口就会形成死循环
func main() {
	println(getsum(3))

	//测试defer语句
	println(1)
	println(2)
	println(3)
	defer f("defer1") //程序走到这一步参数已经传递进去了，但是还没有执行
	println(4)
	defer f("defer2") //可以多个defer语句，当函数执行到最后时，这些defer会逆序执行，最后该函数返回
	println(5)

	//函数的数据类型
	//函数如果不加括号就变成了一个变量，加了扩号就变成了函数的调用，作为变量的时候，其实就是指向一块内存空间，该内存空间中存储着函数体
	//函数如果不加括号作为变量的话，他的类型是由参数和返回结果决定的
	fmt.Printf("%T\n", myfunc) //打印函数的数据类型 func()
	//将myfunc作为变量赋值给函数类型的f1
	var f1 = myfunc
	f1(1, 2) //调用f1其实就是在执行myfunc

	//匿名函数测试
	f2()
	f3 := f2
	f3() //此时调用f3执行的是f2的代码
	//匿名函数定义
	f4 := func() {
		fmt.Println("我是匿名函数f4")
	}
	f4()
	f5 := f4
	f5()

	//匿名函数自己调用自己 只能执行一次，但是可以传参，也可以有返回值
	r1 := func(a, b int) int {
		println("匿名函数自己调用自己", a+b)
		return a + b
	}(1, 2)

	println(r1)
}

func getsum(n int) (r int) {
	if n == 1 {
		return 1
	} else {
		return n + getsum(int(n-1))
	}

}

// defer函数，推迟，延迟
// 在go语言中，使用defer关键字来延迟一个函数或者方法的执行
// defer一般被用于关闭操作
func f(s string) {
	println(s)
}

// 函数的数据类型  func()本身是一个数据类型
func myfunc(a, b int) {
	println(a, b)
}

// 匿名函数测试
func f2() {
	fmt.Println("我是f2函数")
}
